import React, { useRef, useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import type { RulerContentState, MousePosition } from '../types/prevViewTypes';
import { setMousePositions } from '../store/useMousePosition';

// 标尺属性接口：明确所有坐标基于「父容器内容区」
interface RulerProps {
  unit: number; // 每个刻度单位代表的像素数（必须准确，如1单位=10px）
  direction: 'horizontal' | 'vertical'; // 水平/垂直方向
  scrollOffset: number; // 父容器内容区的滚动偏移（像素，非页面滚动）
  color?: string; // 标尺背景色
  tickColor?: string; // 刻度线颜色
  textColor?: string; // 刻度文字颜色
  origin: number; // 0刻度在「父容器内容区」的指定位置（像素，核心参数）
}

// Canvas标尺组件
const Rule: React.FC<RulerProps> = ({
  unit = 10,
  direction = 'horizontal',
  scrollOffset = 0,
  color = 'transparent',
  tickColor = '#64748b',
  textColor = '#334155',
  origin, // 0刻度在父容器内容区的位置（如父容器宽800px，origin=400即中间）
}) => {
  const dispatch = useDispatch();

  const canvasRef = useRef<HTMLCanvasElement>(null);
  const parentRef = useRef<HTMLDivElement>(null); // 父容器ref（统一参考系）
  const [parentSize, setParentSize] = useState<number>(0); // 父容器内容区尺寸（实时更新）

  // 从Redux获取缩放比例，强制转为正数（避免负数/0导致误差）
  const scale = Math.max(useSelector((state: RulerContentState) => state.ruler?.scales) || 1, 0.1);

  // 新增状态管理鼠标位置和显示状态
  const [mousePosition, setMousePosition] = useState<MousePosition>({
    type: 'horizontal',
    visible: false,
    value: 0,
    x: 0,
    y: 0,
  });

  // 1. 监听父容器尺寸变化（避免resize导致误差）
  useEffect(() => {
    const updateParentSize = () => {
      if (!parentRef.current) return;
      // 父容器内容区尺寸（排除padding/border，避免参考系偏移）
      const size = direction === 'horizontal' ? parentRef.current.clientWidth : parentRef.current.clientHeight;
      setParentSize(size);
    };

    // 初始化尺寸
    updateParentSize();
    // 监听窗口resize（若父容器尺寸随窗口变化）
    window.addEventListener('resize', updateParentSize);
    return () => window.removeEventListener('resize', updateParentSize);
  }, [direction]);

  // 2. 鼠标移动：计算与0刻度的相对位置（无误差）
  const handleCanvasMouseMove = (e: React.MouseEvent) => {
    if (!canvasRef.current || !parentRef.current) return;

    const parentRect = parentRef.current.getBoundingClientRect();

    // --------------------------
    // 关键1：计算滚动后0刻度的「当前视觉位置」
    // 逻辑：滚动条向右滚动 → 0刻度向左偏移 → 视觉位置 = 初始origin - 滚动偏移
    // --------------------------
    const currentZeroVisualPos = origin - scrollOffset;

    // --------------------------
    // 关键2：鼠标在父容器中的「视觉坐标」（与滚动后0刻度同参考系）
    // --------------------------
    const mouseVisualPos =
      direction === 'horizontal'
        ? e.clientX - parentRect.left // 鼠标在父容器中的X视觉坐标
        : e.clientY - parentRect.top; // 鼠标在父容器中的Y视觉坐标

    // --------------------------
    // 关键3：计算鼠标相对于「当前0刻度」的刻度值（无滚动偏差）
    // 公式：刻度值 = (鼠标视觉坐标 - 滚动后0刻度视觉坐标) / 单位像素数
    // --------------------------
    const rawValue = (mouseVisualPos - currentZeroVisualPos) / unit;
    const scaleAdjustedValue = Math.round(rawValue / scale); // 对齐整数刻度

    // --------------------------
    // 悬浮框定位（基于父容器视觉坐标，避免滚动后偏移）
    // --------------------------
    let floatX = 0,
      floatY = 0;
    if (direction === 'horizontal') {
      floatX = mouseVisualPos;
      const floatWidth = 60;
      // 边界处理：避免悬浮框超出父容器
      floatX = Math.max(0, Math.min(floatX, parentRect.width - floatWidth / 2));
      floatY = 25; // 固定在标尺下方
    } else {
      floatX = 30; // 固定在标尺右侧
      floatY = mouseVisualPos;
      const floatHeight = 20;
      floatY = Math.max(floatHeight / 2, Math.min(floatY, parentRect.height - floatHeight / 2));
    }

    setMousePosition({ type: direction, visible: true, value: scaleAdjustedValue, x: floatX, y: floatY });
  };
  // 鼠标离开时隐藏刻度值
  const handleCanvasMouseLeave = () => {
    setMousePosition((prev) => ({ ...prev, visible: false }));
  };
  // 鼠标点击时记录刻度值
  const handleCanvasClick = () => {
    dispatch(setMousePositions(mousePosition));
  };

  // 3. 核心绘制逻辑：统一参考系+消除缩放误差
  useEffect(() => {
    if (!canvasRef.current || !parentRef.current || parentSize === 0) return;
    console.log('origin', origin);

    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    // --------------------------
    // 关键1：Canvas尺寸完全匹配父容器（无拉伸，避免误差）
    // --------------------------
    const drawSize = parentSize / scale; // 内部绘制尺寸（消除缩放）
    if (direction === 'horizontal') {
      canvas.width = Math.round(drawSize); // 四舍五入避免小数像素误差
      canvas.height = 30;
      canvas.style.width = `${parentSize}px`; // 样式尺寸=父容器尺寸（无拉伸）
      canvas.style.height = '20px';
    } else {
      canvas.width = 30;
      canvas.height = Math.round(drawSize);
      canvas.style.width = '20px';
      canvas.style.height = `${parentSize}px`;
    }

    // --------------------------
    // 关键2：统一坐标计算（基于父容器内容区）
    // --------------------------
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = color;
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = textColor;
    ctx.strokeStyle = tickColor;
    ctx.lineWidth = 1;

    // 转换核心参数到Canvas内部坐标系（无缩放误差）
    const zeroDrawPos = origin / scale; // 0刻度的内部绘制位置
    const adjustedScroll = scrollOffset / scale; // 滚动偏移的内部绘制位置
    const visibleDrawLength = direction === 'horizontal' ? canvas.width : canvas.height;

    // 计算刻度范围（包含负数，确保覆盖完整可见区）
    // 起始值：0刻度左侧的负数（origin越大，负数范围越广）
    const startValue = Math.floor((adjustedScroll - zeroDrawPos) / unit);
    // 结束值：0刻度右侧的正数
    const endValue = Math.ceil((adjustedScroll + visibleDrawLength - zeroDrawPos) / unit);

    // --------------------------
    // 关键3：绘制刻度（无累积误差）
    // --------------------------
    for (let i = startValue; i <= endValue; i++) {
      // 刻度内部位置 = 0刻度位置 + 刻度值*单位 - 滚动偏移（核心公式）
      const drawPosition = zeroDrawPos + i * unit - adjustedScroll;

      // 刻度长度（层级清晰，避免视觉混淆）
      let tickLength = 0;
      if (i % 10 === 0) tickLength = 8;
      if (i % 100 === 0) tickLength = 15;

      // 只绘制可见区刻度（性能优化）
      if (drawPosition >= 0 && drawPosition <= visibleDrawLength) {
        ctx.beginPath();
        if (direction === 'horizontal') {
          ctx.moveTo(Math.round(drawPosition), 0); // 四舍五入避免亚像素误差
          ctx.lineTo(Math.round(drawPosition), tickLength);
        } else {
          ctx.moveTo(0, Math.round(drawPosition));
          ctx.lineTo(tickLength, Math.round(drawPosition));
        }

        // 0刻度特殊高亮（红色加粗，便于验证位置）
        if (i === 0) {
          ctx.strokeStyle = '#ff6b6b';
          ctx.lineWidth = 2;
        }

        ctx.stroke();
        ctx.strokeStyle = tickColor; // 恢复默认样式
        ctx.lineWidth = 1;

        // 绘制主刻度文字（每100单位，无偏移）
        if (i % 100 === 0) {
          const textPos = Math.round(drawPosition); // 文字位置四舍五入
          if (direction === 'horizontal') {
            ctx.font = '13px Inter, sans-serif';
            ctx.textBaseline = 'top';
            ctx.textAlign = 'center';
            // 文字在刻度线下方2px，无重叠
            ctx.fillText(i.toString(), textPos + 14, tickLength - 2);
          } else {
            ctx.save();
            ctx.font = '13px Inter, sans-serif';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            // 垂直文字向右旋转90度（避免反向）
            const textX = tickLength + 10;
            ctx.translate(textX, textPos);
            ctx.rotate(-Math.PI / 2);
            ctx.fillText(i.toString(), 10, -4);
            ctx.restore();
          }
        }
      }
    }

    // 透明边框（避免默认样式干扰）
    ctx.strokeStyle = 'transparent';
    ctx.strokeRect(0, 0, canvas.width, canvas.height);
  }, [unit, direction, scrollOffset, origin, scale, parentSize, color, tickColor, textColor]);

  // 外层父容器：统一所有坐标参考系
  return (
    <div ref={parentRef} style={{ position: 'relative', width: '100%', height: '100%' }}>
      <canvas
        ref={canvasRef}
        style={{
          pointerEvents: 'auto',
          position: 'absolute', // 绝对定位确保与父容器内容区对齐
          top: 0,
          left: 0,
          userSelect: 'none',
        }}
        aria-label={`${direction === 'horizontal' ? '水平' : '垂直'}标尺（无误差）`}
        onClick={handleCanvasClick}
        onMouseMove={handleCanvasMouseMove}
        onMouseLeave={handleCanvasMouseLeave}
      />
      {mousePosition.visible && (
        <div
          style={{
            position: 'absolute',
            backgroundColor: 'rgba(0, 0, 0, 0.7)',
            color: 'white',
            padding: '2px 6px',
            borderRadius: '3px',
            fontSize: '12px',
            pointerEvents: 'none', // 避免干扰鼠标事件
            left: direction === 'horizontal' ? `${mousePosition.x}px` : '0px',
            top: direction === 'horizontal' ? '25px' : `${mousePosition.y}px`,
            transform: `translateX(${direction === 'horizontal' ? '-50%' : '50%'})`, // 水平方向居中对齐鼠标
          }}
        >
          {mousePosition.value}-{mousePosition.x}-{mousePosition.y}
        </div>
      )}
    </div>
  );
};

export default Rule;
